package Test;

import static org.junit.Assert.*;


import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import View.BuildingGUI;

import Dispatcher.*;


public class DispatcherFunctionalTest {
	
	//dispatcher to run all test cases on
	private static GroupDispatcher dispatcher;
	private static BuildingGUI gui;
	
	//receive these kind of messages
	static final int RECEIVED_INIT = 1;
	static final int RECEIVED_UPDATE = 4;

	
	//create the group dispatcher
	@BeforeClass
	public static void setUp() throws Exception {
		dispatcher = new GroupDispatcher();
		gui = new BuildingGUI(dispatcher);
		gui.setVisible(true);
		UpdateThread ut = new UpdateThread(dispatcher);
		ut.start();

	}
	
	//after all tests have run, close sockets and other clean-up
	@AfterClass
	public static void tearDown() throws Exception {
//		dispatcher.finalize();
		
	}
	
	//Tests if the server socket is bound to an address
	@Test
	public void testSocketActive(){
		assertTrue(dispatcher.serverSocket.isBound());
	}
	
	//Tests that the communications threads are created and started
	@Test
	public void testCommunicationThreadsActive(){
		assertTrue(dispatcher.commThreads.size()==10);
	}
	
	//Tests that communications threads are ready to communicate
	@Test
	public void testCommunicationsListening() {
		for(int i=0;i<dispatcher.commThreads.size();i++){
			assertTrue(dispatcher.commThreads.get(i).isAlive());
		}
	}
	
	//Test if initialization code from 1 elevator is correctly read
	@Test
	public void testRegisterElevator(){
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			System.out.println("Thread Interrupted");
		}
		assertTrue(dispatcher.elevators.size() == 1);
		
		
	}
	
	//Tests if the update request are sent from the dispatcher to the elevators
	@Test
	public void testRequestUpdate(){
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			System.out.println("Thread Interrupted");
		}
		assertTrue(dispatcher.status.size() == 1);
	}
	
	@Test
	public void testHallCallGoingUp() throws InterruptedException{
		dispatcher.processHallCall(5, 1);
		Thread.sleep(1000);
		assertTrue(dispatcher.status.size() == 1);
		ElevatorStatus s = dispatcher.status.values().iterator().next();
		assertTrue(s.getNextDest() == 5);
		Thread.sleep(5000);
		assertTrue(dispatcher.status.size() == 1);
		while(dispatcher.status.values().iterator().next().getCurrentFloor() != 5) Thread.sleep(1);
		assertTrue(dispatcher.status.values().iterator().next().getCurrentFloor() == 5);
	}
	
	@Test
	public void testHallCallGoingDown() throws InterruptedException{
		dispatcher.processHallCall(1, -1);
		Thread.sleep(1000);
		assertTrue(dispatcher.status.size() == 1);
		ElevatorStatus s = dispatcher.status.values().iterator().next();
		assertTrue(s.getNextDest() == 1);
		Thread.sleep(5000);
		assertTrue(dispatcher.status.size() == 1);
		while(dispatcher.status.values().iterator().next().getCurrentFloor() != 1) Thread.sleep(1);
		assertTrue(dispatcher.status.values().iterator().next().getCurrentFloor() == 1);
	}
	
}
